package cn.edu.ncut.cs.springboot.petmanagementsystem.controller;

import cn.edu.ncut.cs.springboot.petmanagementsystem.common.Result;
import cn.edu.ncut.cs.springboot.petmanagementsystem.mapper.OrderMapper;
import cn.edu.ncut.cs.springboot.petmanagementsystem.mapper.ProductMapper;
import cn.edu.ncut.cs.springboot.petmanagementsystem.mapper.ServiceReservationMapper;
import cn.edu.ncut.cs.springboot.petmanagementsystem.pojo.Order;
import cn.edu.ncut.cs.springboot.petmanagementsystem.pojo.Product;
import cn.edu.ncut.cs.springboot.petmanagementsystem.pojo.ServiceReservation;
import cn.edu.ncut.cs.springboot.petmanagementsystem.service.ExportService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.transaction.Transactional;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@RestController
@RequestMapping("/admin")
@Tag(name = "系统管理模块")
public class AdminController {

    @Autowired
    private ProductMapper productMapper;

    @Autowired
    private ServiceReservationMapper reservationMapper;

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private ExportService exportService;

    @Operation(summary = "管理端首页统计数据展示")
    @GetMapping("/dashboard")
    public Result<?> getDashboard() {
        try {
            Map<String, Object> dashboard = new HashMap<>();
            dashboard.put("totalPets", 0);
            dashboard.put("totalUsers", 0);
            dashboard.put("totalOrders", 0);
            dashboard.put("totalRevenue", 0);
            dashboard.put("todayOrders", 0);
            dashboard.put("todayRevenue", 0);
            return Result.success(dashboard);
        } catch (Exception e) {
            log.error("获取管理端首页数据失败", e);
            return Result.error("获取数据失败");
        }
    }

    @Operation(summary = "查询系统操作日志")
    @GetMapping("/logs")
    public Result<?> getLogs(
            @Parameter(description = "页码") @RequestParam(defaultValue = "1") Integer pageNum,
            @Parameter(description = "每页数量") @RequestParam(defaultValue = "10") Integer pageSize) {
        try {
            Map<String, Object> logs = new HashMap<>();
            logs.put("total", 0);
            logs.put("list", new Object[0]);
            return Result.success(logs);
        } catch (Exception e) {
            log.error("查询系统日志失败", e);
            return Result.error("查询日志失败");
        }
    }

    @Operation(summary = "修改系统全局配置")
    @PutMapping("/config")
    public Result<?> updateConfig(@RequestBody Map<String, Object> config) {
        try {
            return Result.success("配置更新成功");
        } catch (Exception e) {
            log.error("更新系统配置失败", e);
            return Result.error("更新配置失败: " + e.getMessage());
        }
    }

    @Operation(summary = "触发数据库备份")
    @GetMapping("/backup")
    public Result<?> triggerBackup() {
        try {
            return Result.success("备份任务已启动");
        } catch (Exception e) {
            log.error("触发数据库备份失败", e);
            return Result.error("备份失败: " + e.getMessage());
        }
    }

    @Operation(summary = "查看系统运行状态（数据库连接、CPU、内存等）")
    @GetMapping("/monitor")
    public Result<?> getMonitor() {
        try {
            Map<String, Object> monitor = new HashMap<>();
            monitor.put("databaseStatus", "正常");
            monitor.put("cpuUsage", 0);
            monitor.put("memoryUsage", 0);
            monitor.put("diskUsage", 0);
            return Result.success(monitor);
        } catch (Exception e) {
            log.error("获取系统监控信息失败", e);
            return Result.error("获取监控信息失败");
        }
    }

    @Operation(summary = "批量操作商品（上架/下架）")
    @PutMapping("/product/batch-status")
    @Transactional
    public Result<?> batchUpdateProductStatus(@RequestBody BatchProductStatusRequest request) {
        try {
            if (request.getProductIds() == null || request.getProductIds().isEmpty()) {
                return Result.error("商品ID列表不能为空");
            }

            if (request.getStatus() == null || (request.getStatus() != 0 && request.getStatus() != 1)) {
                return Result.error("状态值无效，0-下架，1-上架");
            }

            // 批量更新商品状态
            LambdaUpdateWrapper<Product> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.in(Product::getId, request.getProductIds());
            updateWrapper.set(Product::getProductStatus, request.getStatus());
            updateWrapper.set(Product::getUpdateTime, LocalDateTime.now());

            int updatedCount = productMapper.update(null, updateWrapper);

            Map<String, Object> result = new HashMap<>();
            result.put("updatedCount", updatedCount);
            result.put("totalCount", request.getProductIds().size());
            result.put("status", request.getStatus());
            result.put("statusText", request.getStatus() == 1 ? "上架" : "下架");

            return Result.success("批量操作成功", result);
        } catch (Exception e) {
            log.error("批量操作商品状态失败", e);
            return Result.error("批量操作失败: " + e.getMessage());
        }
    }

    @Operation(summary = "批量处理预约（确认/取消）")
    @PutMapping("/reservation/batch-process")
    @Transactional
    public Result<?> batchProcessReservation(@RequestBody BatchReservationProcessRequest request) {
        try {
            if (request.getReservationIds() == null || request.getReservationIds().isEmpty()) {
                return Result.error("预约ID列表不能为空");
            }

            if (request.getAction() == null || (!request.getAction().equals("confirm") && !request.getAction().equals("cancel"))) {
                return Result.error("操作类型无效，confirm-确认，cancel-取消");
            }

            int successCount = 0;
            int failCount = 0;

            for (Long reservationId : request.getReservationIds()) {
                try {
                    ServiceReservation reservation = reservationMapper.selectById(reservationId);
                    if (reservation == null) {
                        failCount++;
                        continue;
                    }

                    if ("confirm".equals(request.getAction())) {
                        // 确认预约
                        if (reservation.getReservationStatus() == 1) { // 待确认
                            reservation.setReservationStatus(2); // 已确认
                            reservation.setUpdateTime(LocalDateTime.now());
                            reservationMapper.updateById(reservation);
                            successCount++;
                        } else {
                            failCount++;
                        }
                    } else if ("cancel".equals(request.getAction())) {
                        // 取消预约
                        if (reservation.getReservationStatus() == 1 || reservation.getReservationStatus() == 2) {
                            reservation.setReservationStatus(5); // 已取消
                            reservation.setUpdateTime(LocalDateTime.now());
                            reservationMapper.updateById(reservation);
                            successCount++;
                        } else {
                            failCount++;
                        }
                    }
                } catch (Exception e) {
                    log.error("处理预约失败，预约ID: " + reservationId, e);
                    failCount++;
                }
            }

            Map<String, Object> result = new HashMap<>();
            result.put("successCount", successCount);
            result.put("failCount", failCount);
            result.put("totalCount", request.getReservationIds().size());
            result.put("action", request.getAction());
            result.put("actionText", "confirm".equals(request.getAction()) ? "确认" : "取消");

            return Result.success("批量处理完成", result);
        } catch (Exception e) {
            log.error("批量处理预约失败", e);
            return Result.error("批量处理失败: " + e.getMessage());
        }
    }

    @Operation(summary = "数据清理（清理过期数据、无效数据等）")
    @PostMapping("/cleanup")
    public Result<?> cleanupData(@RequestBody(required = false) CleanupRequest request) {
        try {
            Map<String, Object> result = new HashMap<>();
            int totalCleaned = 0;

            if (request == null || request.getTypes() == null || request.getTypes().isEmpty()) {
                // 如果未指定清理类型，执行默认清理
                request = new CleanupRequest();
                request.setTypes(List.of("expired_reservations", "cancelled_orders"));
            }

            for (String type : request.getTypes()) {
                int cleaned = 0;
                switch (type) {
                    case "expired_reservations":
                        // 清理30天前已完成的预约记录
                        LambdaQueryWrapper<ServiceReservation> reservationWrapper = new LambdaQueryWrapper<>();
                        reservationWrapper.eq(ServiceReservation::getReservationStatus, 4); // 已完成
                        reservationWrapper.lt(ServiceReservation::getCompletionTime, 
                            LocalDateTime.now().minusDays(30));
                        List<ServiceReservation> expiredReservations = reservationMapper.selectList(reservationWrapper);
                        // 注意：实际项目中应该使用逻辑删除，这里仅作示例
                        cleaned = expiredReservations.size();
                        result.put("expiredReservations", cleaned);
                        break;

                    case "cancelled_orders":
                        // 清理60天前已取消的订单
                        LambdaQueryWrapper<Order> orderWrapper = new LambdaQueryWrapper<>();
                        orderWrapper.eq(Order::getOrderStatus, 5); // 已取消
                        orderWrapper.lt(Order::getUpdateTime, LocalDateTime.now().minusDays(60));
                        List<Order> cancelledOrders = orderMapper.selectList(orderWrapper);
                        // 注意：实际项目中应该使用逻辑删除，这里仅作示例
                        cleaned = cancelledOrders.size();
                        result.put("cancelledOrders", cleaned);
                        break;

                    case "old_logs":
                        // 清理旧日志（如果有日志表）
                        cleaned = 0;
                        result.put("oldLogs", cleaned);
                        break;

                    default:
                        log.warn("未知的清理类型: " + type);
                        break;
                }
                totalCleaned += cleaned;
            }

            result.put("totalCleaned", totalCleaned);
            result.put("cleanupTime", LocalDateTime.now());

            return Result.success("数据清理完成", result);
        } catch (Exception e) {
            log.error("数据清理失败", e);
            return Result.error("数据清理失败: " + e.getMessage());
        }
    }

    @Operation(summary = "导出系统报表")
    @GetMapping("/report/export")
    public ResponseEntity<String> exportSystemReport(
            @Parameter(description = "报表类型：orders-订单报表，reservations-预约报表，all-全部") 
            @RequestParam(defaultValue = "all") String reportType) {
        try {
            StringBuilder reportContent = new StringBuilder();
            
            // CSV头部（BOM for Excel中文支持）
            reportContent.append("\uFEFF");
            reportContent.append("系统报表导出\n");
            reportContent.append("报表类型: ").append(reportType).append("\n");
            reportContent.append("导出时间: ").append(LocalDateTime.now().format(
                java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))).append("\n\n");

            if ("orders".equals(reportType) || "all".equals(reportType)) {
                // 导出订单报表
                String ordersReport = exportService.exportOrders(null);
                reportContent.append("=== 订单报表 ===\n");
                reportContent.append(ordersReport).append("\n\n");
            }

            if ("reservations".equals(reportType) || "all".equals(reportType)) {
                // 导出预约报表
                reportContent.append("=== 预约报表 ===\n");
                
                LambdaQueryWrapper<ServiceReservation> wrapper = new LambdaQueryWrapper<>();
                wrapper.orderByDesc(ServiceReservation::getCreateTime);
                List<ServiceReservation> reservations = reservationMapper.selectList(wrapper);

                reportContent.append("预约ID,预约单号,用户ID,服务类型ID,宠物ID,预约日期,预约时间,状态,总金额,创建时间\n");
                for (ServiceReservation reservation : reservations) {
                    reportContent.append(reservation.getId()).append(",");
                    reportContent.append(reservation.getReservationNo()).append(",");
                    reportContent.append(reservation.getUserId()).append(",");
                    reportContent.append(reservation.getServiceTypeId()).append(",");
                    reportContent.append(reservation.getPetId()).append(",");
                    reportContent.append(reservation.getReservationDate() != null ? 
                        reservation.getReservationDate().toString() : "").append(",");
                    reportContent.append(reservation.getReservationTime() != null ? 
                        reservation.getReservationTime().toString() : "").append(",");
                    reportContent.append(reservation.getReservationStatus()).append(",");
                    reportContent.append(reservation.getTotalAmount()).append(",");
                    reportContent.append(reservation.getCreateTime() != null ? 
                        reservation.getCreateTime().toString() : "").append("\n");
                }
            }

            // 设置响应头
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.parseMediaType("text/csv;charset=UTF-8"));
            headers.setContentDispositionFormData("attachment", 
                "system_report_" + reportType + "_" + 
                LocalDateTime.now().format(java.time.format.DateTimeFormatter.ofPattern("yyyyMMddHHmmss")) + ".csv");
            headers.add(HttpHeaders.CONTENT_ENCODING, "UTF-8");

            return ResponseEntity.ok()
                    .headers(headers)
                    .body(reportContent.toString());

        } catch (Exception e) {
            log.error("导出系统报表失败", e);
            return ResponseEntity.badRequest()
                    .header(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN_VALUE)
                    .body("导出失败: " + e.getMessage());
        }
    }

    @Data
    public static class BatchProductStatusRequest {
        private List<Long> productIds;
        private Integer status; // 0-下架，1-上架
    }

    @Data
    public static class BatchReservationProcessRequest {
        private List<Long> reservationIds;
        private String action; // confirm-确认，cancel-取消
    }

    @Data
    public static class CleanupRequest {
        private List<String> types; // expired_reservations, cancelled_orders, old_logs
    }
}
